﻿using System;
using System.Linq;
using COFE.Core;
using COFE.Core.Profile;
using COFE.Core.UnitTest;
using NUnit.Framework;
using System.Reflection;
using System.IO;
using System.Configuration;
using COFE.Core.Actions;
using COFE.Core.Logger;

namespace COFE.Data.UnitTest
{
    public class DBTestUserCreator : ITestUserCreator
    {
        public static DBTestUserCreator Instance = new DBTestUserCreator();

        static DBTestUserCreator()
        {
            DummyDBPropertyProvider.EnableDummySecondaryPropertyProvider();
        }

        public void ClearCache()
        {
            //using (var context = new COFEDB2())
            //{
            //COFEDBShared.DBOperations.UpdateDatabase((context) =>
            //    {
            //        var temp = context.Volumes.FirstOrDefault((v) => v.VolumeId == "TEMP");
            //        if (temp != null)
            //        {
            //            context.Volumes.DeleteObject(temp);
            //            context.SaveChanges();
            //        }
            //    });
            //}

            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"Volumes\"");
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"Users\"");
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"Permissions\"");
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"LookupFilter\"");

            //}
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"EntryProperties\"");
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"EntryProperties_Int32\"");
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"EntryProperties_String\"");
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"EntryProperties_Bool\"");
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"EntryProperties_DateTime\"");
            //COFEDBShared.Context.ExecuteStoreCommand("DELETE FROM \"EntryProperties_Guid\"");
        }

        public string CopyDatabase(string tempDirectory)
        {
            //string dbFile = Path.Combine(Path.GetDirectoryName(
            //    Assembly.GetExecutingAssembly().Location), "COFEDB2.sqlite");
            string dbFile = "COFEDB2.sqlite";
            string destFile = Path.Combine(tempDirectory, "COFEDB2.sqlite");
            File.Copy(dbFile, destFile);
            return destFile;
        }

        public Core.IUserProfile CreateUser(string name, params Tuple<string, string, string>[] registerVolume)
        {
            ClearCache();
            COFEShared.Register();
            COFEActionShared.Register();            

            string connectionString = null; //undefined
            if (registerVolume.Any(t => t.Item2 == "TEMP"))
            {
                string dbPath = CopyDatabase(registerVolume.First(t => t.Item2 == "TEMP")
                    .Item3.Replace("path=", ""));
                connectionString = ConfigurationManager.ConnectionStrings["COFEDB2"].ConnectionString.Replace("COFEDB2.sqlite", dbPath);
            }

            COFEDBShared.Register(connectionString, true);
            
            //COFEActionShared.WorkScheduler.EventDispatcher.SpawnConsoleListener();
            //COFEActionShared.WorkScheduler.TotalThread = 1;

            DBUserProfile.Delete(name);

            var lookupUser = COFEDBShared.DBOperations.ReadDatabase(
                (context) => context.Users.FirstOrDefault(u => u.UserId == name)
                );
            Assert.IsNull(lookupUser);


            var profile = DBUserProfile.Create(name, "password");
            foreach (var pp in registerVolume)
            {

                COFEShared.VolumeRegistrar.RegisterVolume(
                    pp.Item1, pp.Item2,
                    pp.Item3, VolumeAccessMode.All);
                profile.RegisterVolume(pp.Item2);

            }
            //profile.RegisterVolume(pp.Item1, pp.Item2, pp.Item3.Split(','));

            foreach (var pp in registerVolume)
            {
                Assert.IsNotNull(COFEShared.VolumeRegistrar.LookupRegisterVolume(pp.Item2));
                Assert.IsTrue(profile.Volumes.PrimaryVolumes.Any((pv) => pv.ListerKey == pp.Item2)
                    || profile.Volumes.SecondaryVolumes.Any(sv => sv.ListerKey == pp.Item2));
            }

            return DBUserProfile.Login(name, "password");

        }
    }
}
